{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# numpy入门"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### NumPy 数组\n",
    "NumPy 数组是包含相同类型值的网格。NumPy 数组有两种形式：向量和矩阵。  \n",
    "严格地讲，向量是一维数组，矩阵是多维数组。在某些情况下，矩阵只有一行或一列。  \n",
    "首先将 NumPy 导入 Jupyter notebook："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "从 Python 列表中创建 NumPy 数组  \n",
    "我们先创建一个 Python 列表："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "my_list = [1, 2, 3, 4, 5]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "通过这个列表，我们可以简单地创建一个名为 my_numpy_list 的 NumPy 数组，显示结果："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 2, 3, 4, 5])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "my_numpy_list = np.array(my_list)\n",
    "my_numpy_list #This line show the result of the array generated"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "刚才我们将一个 Python 列表转换成一维数组。要想得到二维数组，我们要创建一个元素为列表的列表，如下所示："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 2, 3],\n",
       "       [5, 4, 1],\n",
       "       [3, 6, 7]])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "second_list = [[1,2,3], [5,4,1], [3,6,7]]\n",
    "new_2d_arr = np.array(second_list)\n",
    "new_2d_arr "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**使用 arange() 内置函数创建 NumPy 数组:**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 1 2 3 4 5 6 7 8 9]\n"
     ]
    }
   ],
   "source": [
    "# 与 Python 的 range() 内置函数相似，我们可以用 arange() 创建一个 NumPy 数组。\n",
    "my_list = np.arange(10)#ORmy_list = np.arange(0,10)\n",
    "# 这产生了 0~10 的十个数字。\n",
    "print(my_list)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.  0.5 1.  1.5 2.  2.5 3.  3.5 4.  4.5]\n"
     ]
    }
   ],
   "source": [
    "# 要注意的是 arange() 函数中的第三个参数表示步长，可以设置为浮点数。如下所示：\n",
    "my_list = np.arange(0,5,0.5)\n",
    "print(my_list)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0. 0. 0. 0. 0. 0. 0.]\n",
      "[1. 1. 1. 1. 1.]\n",
      "[[0. 0. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0.]]\n"
     ]
    }
   ],
   "source": [
    "# 还可以创建有 7 个 0 的一维数组：\n",
    "my_zeros = np.zeros(7)\n",
    "print(my_zeros)\n",
    "#也可以创建有 5 个 1 的一维数组：\n",
    "my_ones = np.ones(5)\n",
    "print(my_ones)\n",
    "#同样，我们可以生成内容都为 0 的 3 行 5 列二维数组：\n",
    "two_d = np.zeros((3,5))\n",
    "print(two_d)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**使用 linspace() 内置函数创建 NumPy 数组**   \n",
    "linspace() 函数返回的数字都具有指定的间隔。也就是说，如果我们想要 1 到 3 中间隔相等的 15 个点，我们只需使用以下命令："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1.         1.14285714 1.28571429 1.42857143 1.57142857 1.71428571\n",
      " 1.85714286 2.         2.14285714 2.28571429 2.42857143 2.57142857\n",
      " 2.71428571 2.85714286 3.        ]\n"
     ]
    }
   ],
   "source": [
    "lin_arr = np.linspace(1, 3, 15)\n",
    "print(lin_arr)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "该命令可生成一维向量。  \n",
    "与 arange() 函数不同，linspace() 的第三个参数是要创建的数据点数量。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**在 NumPy 中创建一个恒等矩阵**  \n",
    "处理线性代数时，恒等矩阵是非常有用的。一般而言，恒等矩阵是一个二维方矩阵，也就是说在这个矩阵中列数与行数相等。有一点要注意的是，恒等矩阵的对角线都是 1，其他的都是 0。恒等矩阵一般只有一个参数，下述命令说明了要如何创建恒等矩阵："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "my_matrx = np.eye(6) #6 is the number of columns/rows you want"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**用 NumPy 创建一个随机数组成的数组**  \n",
    "我们可以使用 rand()、randn() 或 randint() 函数生成一个随机数组成的数组。  \n",
    "使用 random.rand()，我们可以生成一个从 0\\~1 均匀产生的随机数组成的数组。  \n",
    "例如，如果想要一个由 4 个对象组成的一维数组，且这 4 个对象均匀分布在 0\\~1，可以这样做：  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.45615033 0.56843395 0.0187898  0.6176355 ]\n"
     ]
    }
   ],
   "source": [
    "# np.random.seed(0)\n",
    "my_rand = np.random.rand(4)\n",
    "print(my_rand)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0.61209572 0.616934   0.94374808 0.6818203 ]\n",
      " [0.3595079  0.43703195 0.6976312  0.06022547]\n",
      " [0.66676672 0.67063787 0.21038256 0.1289263 ]\n",
      " [0.31542835 0.36371077 0.57019677 0.43860151]\n",
      " [0.98837384 0.10204481 0.20887676 0.16130952]]\n"
     ]
    }
   ],
   "source": [
    "# 如果我们想要一个有 5 行 4 列的二维数组，则：\n",
    "my_rand = np.random.rand(5, 4)\n",
    "print(my_rand)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-0.35955316 -0.20642094  0.48842647 -0.83833097  0.38116374 -0.99090328\n",
      "  1.01788005]\n"
     ]
    }
   ],
   "source": [
    "# 使用 randn()，我们可以从以 0 为中心的标准正态分布或高斯分布中产生随机样本。例如，我们这样生成 7 个随机数：\n",
    "my_randn = np.random.randn(7)\n",
    "print(my_randn)\n",
    "# 绘制结果后会得到一个正态分布曲线。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-1.25279536,  0.77749036, -1.61389785, -0.21274028, -0.89546656],\n",
       "       [ 0.3869025 , -0.51080514, -1.18063218, -0.02818223,  0.42833187],\n",
       "       [ 0.06651722,  0.3024719 , -0.63432209, -0.36274117, -0.67246045]])"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 同样地，如需创建一个 3 行 5 列的二维数组，这样做即可：\n",
    "np.random.randn(3,5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([4, 1, 2, 3, 4, 3, 2, 3, 2, 1])"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 最后，我们可以使用 randint() 函数生成整数数组。randint() 函数最多可以有三个参数：最小值（包含），最大值（不包含）以及数组的大小。\n",
    "np.random.randint(1,5,10) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**将一维数组转换成二维数组**  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0.21550768 0.94737059 0.73085581 0.25394164 0.21331198]\n",
      " [0.51820071 0.02566272 0.20747008 0.42468547 0.37416998]\n",
      " [0.46357542 0.27762871 0.58678435 0.86385561 0.11753186]\n",
      " [0.51737911 0.13206811 0.71685968 0.3960597  0.56542131]]\n"
     ]
    }
   ],
   "source": [
    "# 先创建一个有 25 个随机整数的一维数组：\n",
    "arr = np.random.rand(20)\n",
    "# 然后使用 reshape() 函数将其转换为二维数组：\n",
    "arr = arr.reshape(4,5)\n",
    "print(arr)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**注意**：reshape() 转换的行列数相乘后要与元素数量相等。上例中的 arr 包含 20 个元素，因此新矩阵 4\\*5=20"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**定位 NumPy 数组中的最大值和最小值**  \n",
    "使用 max() 和 min() 函数，我们可以得到数组中的最大值或最小值："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr_2 = np.random.randint(0, 20, 10)\n",
    "print(arr_2.max()) #This gives the highest value in the array\n",
    "print(arr_2.min()) #This gives the lowest value in the array"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用 argmax() 和 argmin() 函数，我们可以定位数组中最大值和最小值的索引："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4\n",
      "0\n"
     ]
    }
   ],
   "source": [
    "print(arr_2.argmax()) #This shows the index of the highest value in the array \n",
    "print(arr_2.argmin()) #This shows the index of the lowest value in the array"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "假设存在大量数组，而你需要弄清楚数组的形态，你想知道这个数组是一维数组还是二维数组，只需要使用 shape 函数即可："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(4, 5)\n",
      "[[[0.21550768 0.94737059 0.73085581 0.25394164 0.21331198]\n",
      "  [0.51820071 0.02566272 0.20747008 0.42468547 0.37416998]\n",
      "  [0.46357542 0.27762871 0.58678435 0.86385561 0.11753186]\n",
      "  [0.51737911 0.13206811 0.71685968 0.3960597  0.56542131]]]\n",
      "(1, 4, 5)\n"
     ]
    }
   ],
   "source": [
    "print(arr.shape)\n",
    "# 维度扩展, 参数为扩展维度的位置\n",
    "arr_1 = (np.expand_dims(arr,0))\n",
    "print(arr_1)\n",
    "print(arr_1.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**从 NumPy 数组中索引／选择多个元素（组）**  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 在 NumPy 数组中进行索引与 Python 类似，只需输入想要的索引即可：  \n",
    "my_array = np.arange(0,11)\n",
    "my_array[8] #This gives us the value of element at index 8"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 5,  6,  7,  8,  9, 10])"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 为了获得数组中的一系列值，我们可以使用切片符「:」，就像在 Python 中一样：\n",
    "my_array[2:6] #This returns everything from index 2 to 6(exclusive)\n",
    "my_array[:6] #This returns everything from index 0 to 6(exclusive)\n",
    "my_array[5:] #This returns everything from index 5 to the end of the array."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "60"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 类似地，我们也可以通过使用 [ ][ ] 或 [,] 在二维数组中选择元素。\n",
    "# 使用 [ ][ ] 从下面的二维数组中抓取出值「60」：\n",
    "two_d_arr = np.array([[10,20,30], [40,50,60], [70,80,90]])\n",
    "two_d_arr[1][2] #The value 60 appears is in row index 1, and column index 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "20"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用 [,] 从上面的二维数组中抓取出值「20」：\n",
    "two_d_arr[0,1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[10, 20],\n",
       "       [40, 50]])"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 也可以用切片符抓取二维数组的子部分。使用下面的操作从数组中抓取一些元素：\n",
    "two_d_arr[:1, :2] # This returns [[10, 20]]\n",
    "two_d_arr[:2, 1:] # This returns ([[20, 30], [50, 60]])\n",
    "two_d_arr[:2, :2] #This returns ([[10, 20], [40, 50]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[10, 20, 30],\n",
       "       [40, 50, 60]])"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 我们还可以索引一整行或一整列。只需使用索引数字即可抓取任意一行：\n",
    "two_d_arr[0] #This grabs row 0 of the array ([10, 20, 30])\n",
    "two_d_arr[:2] #This grabs everything before row 2 ([[10, 20, 30], [40, 50, 60]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False, False, False, False, False, False,  True,  True,  True,\n",
       "        True])"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 还可以使用 &、|、<、> 和 == 运算符对数组执行条件选择和逻辑选择，从而对比数组中的值和给定值：\n",
    "new_arr = np.arange(5,15)\n",
    "new_arr > 10 #This returns TRUE where the elements are greater than 10 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([11, 12, 13, 14])"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 现在我们可以输出符合上述条件的元素：\n",
    "bool_arr = new_arr > 10\n",
    "new_arr[bool_arr] #This returns elements greater than 10 [11, 12, 13, 14]\n",
    "new_arr[new_arr>10] #A shorter way to do what we have just done"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([7, 8, 9])"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 组合使用条件运算符和逻辑运算符，我们可以得到值大于 6 小于 10 的元素：\n",
    "new_arr[(new_arr>6) & (new_arr<10)]\n",
    "# 预期结果为：([7, 8, 9])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": true,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
